package com.cooldatasoft.taskManager.user.gui;

import java.util.Arrays;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;

import com.cooldatasoft.domain.service.EventService;
import com.cooldatasoft.security.TaskManagerSecurityManager;
import com.cooldatasoft.taskManager.component.MyCalendarEvent;
import com.cooldatasoft.taskManager.component.MyEventProvider;
import com.vaadin.addon.calendar.gwt.client.ui.VCalendar;
import com.vaadin.addon.calendar.ui.Calendar;
import com.vaadin.addon.calendar.ui.CalendarComponentEvents;
import com.vaadin.addon.calendar.ui.CalendarComponentEvents.BackwardEvent;
import com.vaadin.addon.calendar.ui.CalendarComponentEvents.BackwardHandler;
import com.vaadin.addon.calendar.ui.CalendarComponentEvents.DateClickEvent;
import com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventClick;
import com.vaadin.addon.calendar.ui.CalendarComponentEvents.EventResize;
import com.vaadin.addon.calendar.ui.CalendarComponentEvents.ForwardEvent;
import com.vaadin.addon.calendar.ui.CalendarComponentEvents.ForwardHandler;
import com.vaadin.addon.calendar.ui.CalendarComponentEvents.MoveEvent;
import com.vaadin.addon.calendar.ui.CalendarComponentEvents.RangeSelectEvent;
import com.vaadin.addon.calendar.ui.CalendarComponentEvents.WeekClick;
import com.vaadin.addon.calendar.ui.CalendarComponentEvents.WeekClickHandler;
import com.vaadin.addon.calendar.ui.handler.BasicWeekClickHandler;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Item;
import com.vaadin.data.util.BeanItem;
import com.vaadin.data.validator.StringLengthValidator;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.DefaultFieldFactory;
import com.vaadin.ui.Field;
import com.vaadin.ui.Form;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.NativeButton;
import com.vaadin.ui.Panel;
import com.vaadin.ui.PopupDateField;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.Window.Notification;

@Configurable(preConstruction = true)
public class CalendarView extends CustomComponent {

	@AutoGenerated
	private VerticalLayout mainLayout;
	@AutoGenerated
	private Panel calendarPanel;
	@AutoGenerated
	private VerticalLayout calendarLayout;
	@AutoGenerated
	private Calendar calendarComponent;
	@AutoGenerated
	private HorizontalLayout buttonsLayout;

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

	

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

	

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

	

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

	

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

	

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

	

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

	

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

	private enum Mode {
		ADD, EDIT;
	}

	private enum CurrentView {
		DAY, WEEK, MONTH;
	}
	
	private Mode mode;
	private CurrentView currentView;
	private NativeButton weekViewButton;
	private NativeButton monthViewButton;
	private NativeButton nextButton;
	private NativeButton prevButton;
	private NativeButton submitBtn;
	private NativeButton deleteBtn;
	private NativeButton closeBtn;

	private GregorianCalendar cal;
	private com.cooldatasoft.domain.model.Event event0;
	private FormWithComplexLayout form;
	private BeanItem<com.cooldatasoft.domain.model.Event> eventItem;
	private com.cooldatasoft.domain.model.Event selectedEventForEdit;

	private MyEventProvider dataSource;
	private Window eventWindowModal;

	@Autowired
	private EventService eventService;

	@Autowired
	private TaskManagerSecurityManager securityManager;
	private MyCalendarEvent defaultCalEvent;

	private static final long serialVersionUID = 1L;

	public CalendarView() {
		buildMainLayout();
		setCompositionRoot(mainLayout);
		customizeCalendar();
		addSwitchButtons();
		customizeFormButtons();
	}

	private void customizeCalendar() {
//		calendarComponent.setLocale(new Locale("sk"));
		calendarComponent.setLocale(Locale.UK);
		dataSource = new MyEventProvider();
		calendarComponent.setEventProvider(dataSource);
		calendarComponent.setImmediate(true);

		currentView = CurrentView.WEEK;
		cal = new GregorianCalendar(calendarComponent.getTimeZone(),
				calendarComponent.getLocale());
		
		addCalendarEventListeners();

	}

	private void addCalendarEventListeners() {
		// Add date click listener
		
		calendarComponent
				.setHandler(new CalendarComponentEvents.DateClickHandler() {

					public void dateClick(DateClickEvent event) {
						Calendar cal = event.getComponent();
						long currentCalDateRange = cal.getEndDate().getTime()
								- cal.getStartDate().getTime();
						if (currentCalDateRange < VCalendar.DAYINMILLIS) {
							// Change the date range to the current week
						} else {
							// Change the date range to the clicked day
							cal.setStartDate(event.getDate());
							cal.setEndDate(event.getDate());
							
							currentView = CurrentView.DAY;
							
							weekViewButton.setEnabled(true);
							monthViewButton.setEnabled(true);
						}
						updateCalendarCaption();
					}
				});
		
		calendarComponent.setHandler(new BasicWeekClickHandler() {
			@Override
			protected void setDates(WeekClick event, Date start, Date end) {
				super.setDates(event, start, end);
				
				currentView = CurrentView.WEEK;
				
				weekViewButton.setEnabled(false);
				monthViewButton.setEnabled(true);
				
				updateCalendarCaption();
			}
		});

		calendarComponent
				.setHandler(new CalendarComponentEvents.EventClickHandler() {

					@Override
					public void eventClick(EventClick event) {
						showEventPopup(
								(MyCalendarEvent) event.getCalendarEvent(),
								false);
					}
				});

		calendarComponent
				.setHandler(new CalendarComponentEvents.RangeSelectHandler() {

					@Override
					public void rangeSelect(RangeSelectEvent event) {
						handleRangeSelect(event);
					}
				});

		calendarComponent
				.setHandler(new CalendarComponentEvents.EventMoveHandler() {

					@Override
					public void eventMove(MoveEvent event) {
						MyCalendarEvent myCalEvent;
						if ((myCalEvent = (MyCalendarEvent) event
								.getCalendarEvent()).getIdent() != 0) {
							Long oldStart = myCalEvent.getStart().getTime();
							Long newStart = event.getNewStart().getTime();
							Long startDiff = oldStart - newStart;
							Long newEnd = myCalEvent.getEnd().getTime()
									- startDiff;

							myCalEvent.setStart(event.getNewStart());

							myCalEvent.setEnd(new Date(newEnd));

							handleMoveEvent(myCalEvent);
						} else {
							calendarComponent.requestRepaint();
							getWindow().showNotification("You cannot move event of type \"Project\"",Notification.TYPE_WARNING_MESSAGE);
						}
					}
				});

		calendarComponent
				.setHandler(new CalendarComponentEvents.EventResizeHandler() {

					@Override
					public void eventResize(EventResize event) {
						Date newStart = event.getNewStartTime();
						Date newEnd = event.getNewEndTime();

						MyCalendarEvent myCalEvent = (MyCalendarEvent) event
								.getCalendarEvent();

						myCalEvent.setStart(newStart);
						myCalEvent.setEnd(newEnd);

						handleResizeEvent(myCalEvent);
					}
				});
	}

	private void addSwitchButtons() {
		weekViewButton = new NativeButton("Week view");
		weekViewButton.setStyleName("weekBtn");
		monthViewButton = new NativeButton("Month view");
		monthViewButton.setStyleName("monthBtn");
		
		nextButton = new NativeButton("Next");
		nextButton.setStyleName("nextBtn");
		nextButton.setCaption("");
		nextButton.setDescription("Next");
		
		prevButton = new NativeButton("Previous");
		prevButton.setStyleName("prevBtn");
		prevButton.setCaption("");
		prevButton.setDescription("Previous");
		
		weekViewButton.setEnabled(false);
		monthViewButton.setEnabled(true);

		weekViewButton.addListener(new Button.ClickListener() {
			
			@Override
			public void buttonClick(ClickEvent event) {
				cal = new GregorianCalendar(calendarComponent.getTimeZone(),calendarComponent.getLocale());
				WeekClickHandler handler = (WeekClickHandler) calendarComponent.getHandler(WeekClick.EVENT_ID);
				handler.weekClick(new WeekClick(calendarComponent, cal.get(GregorianCalendar.WEEK_OF_YEAR), cal.get(GregorianCalendar.YEAR)));

				currentView = CurrentView.WEEK;
				
				weekViewButton.setEnabled(false);
				monthViewButton.setEnabled(true);
				
			}
		});

		monthViewButton.addListener(new Button.ClickListener() {
			
			@Override
			public void buttonClick(ClickEvent event) {
				
				cal = new GregorianCalendar(calendarComponent.getTimeZone(),
						calendarComponent.getLocale());

				// Reset calendar's start time to the target month's first day.
				cal.set(GregorianCalendar.DATE,
						cal.getMinimum(GregorianCalendar.DATE));
				cal.set(GregorianCalendar.HOUR_OF_DAY, 0);
				cal.set(GregorianCalendar.MINUTE, 0);
				cal.set(GregorianCalendar.SECOND, 0);
				cal.set(GregorianCalendar.MILLISECOND, 0);
				calendarComponent.setStartDate(cal.getTime());
				cal.add(GregorianCalendar.MONTH, 1);
				cal.add(GregorianCalendar.DATE, -1);
				calendarComponent.setEndDate(cal.getTime());

				currentView = CurrentView.MONTH;
				
				weekViewButton.setEnabled(true);
				monthViewButton.setEnabled(false);
				
				updateCalendarCaption();
			}
		});

		nextButton.addListener(new Button.ClickListener() {
			
			@Override
			public void buttonClick(ClickEvent event) {
				switch(currentView) {
					case DAY:
						nextDayWeek();
						break;
					case WEEK:
						nextDayWeek();
						break;
					case MONTH:
						nextMonth();
						updateCalendarCaption();
						break;
				}
			}
		});

		prevButton.addListener(new Button.ClickListener() {
			
			@Override
			public void buttonClick(ClickEvent event) {
				switch(currentView) {
					case DAY:
						previousDayWeek();
						break;
					case WEEK:
						previousDayWeek();
						break;
					case MONTH:
						previousMonth();
						updateCalendarCaption();
						break;
				}
			}
		});
		
		buttonsLayout.addComponent(prevButton);
		buttonsLayout.addComponent(weekViewButton);
		buttonsLayout.addComponent(monthViewButton);
		buttonsLayout.addComponent(nextButton);
	}

	private void handleRangeSelect(RangeSelectEvent event) {
		Date start = event.getStart();
		Date end = event.getEnd();

		MyCalendarEvent newCalEvent = new MyCalendarEvent();
		newCalEvent.setStart(start);
		newCalEvent.setEnd(end);

		showEventPopup(newCalEvent, true);
	}

	private void handleMoveEvent(MyCalendarEvent event) {
		com.cooldatasoft.domain.model.Event selectedEvent = eventService
				.getById(event.getIdent());
		selectedEvent.setEnd(event.getEnd());
		selectedEvent.setStart(event.getStart());
		eventService.updateEvent(selectedEvent);
	}

	private void handleResizeEvent(MyCalendarEvent event) {
		com.cooldatasoft.domain.model.Event selectedEvent = eventService
				.getById(event.getIdent());
		selectedEvent.setEnd(event.getEnd());
		selectedEvent.setStart(event.getStart());
		eventService.updateEvent(selectedEvent);
	}

	private void showEventPopup(MyCalendarEvent event, boolean newEvent) {
		defaultCalEvent = event;

		VerticalLayout vlayout = new VerticalLayout();
		vlayout.setWidth("100%");
		vlayout.setHeight("100%");
		vlayout.setMargin(false);

		eventWindowModal = new Window(null, vlayout);
		eventWindowModal.setWidth("500px");
		eventWindowModal.setHeight("450px");
		eventWindowModal.setModal(true);

		event0 = new com.cooldatasoft.domain.model.Event();
		eventItem = new BeanItem<com.cooldatasoft.domain.model.Event>(event0);
		form = new FormWithComplexLayout(eventItem);

		form.setWriteThrough(false);
		form.setInvalidCommitted(false);

		form.getField("start").setValue(event.getStart());
		form.getField("end").setValue(event.getEnd());

		if (newEvent) {
			mode = Mode.ADD;
			deleteBtn.setVisible(false);
			eventWindowModal.setCaption("Add new event");
		} else {
			mode = Mode.EDIT;
			deleteBtn.setVisible(true);
			selectedEventForEdit = eventService.getById(event.getIdent());
			eventWindowModal.setCaption("Edit selected event");
			form.getField("caption").setValue(event.getCaption());
			form.getField("description").setValue(event.getDescription());
			form.getField("all_day").setValue(event.isAllDay());
		}

		vlayout.addComponent(form);

		HorizontalLayout buttons = new HorizontalLayout();
		buttons.setSpacing(true);
		buttons.setMargin(true);
		buttons.addComponent(submitBtn);
		buttons.addComponent(deleteBtn);
		buttons.addComponent(closeBtn);
		vlayout.addComponent(buttons);
		vlayout.setComponentAlignment(buttons, Alignment.BOTTOM_RIGHT);

		if (event.getIdent() == 0 && !newEvent) {
			form.getField("start").setReadOnly(true);
			form.getField("end").setReadOnly(true);
			form.getField("caption").setReadOnly(true);
			form.getField("description").setReadOnly(true);
			form.getField("all_day").setReadOnly(true);
			submitBtn.setEnabled(false);
			deleteBtn.setEnabled(false);
		} else {
			form.getField("start").setReadOnly(false);
			form.getField("end").setReadOnly(false);
			form.getField("caption").setReadOnly(false);
			form.getField("description").setReadOnly(false);
			form.getField("all_day").setReadOnly(false);
			submitBtn.setEnabled(true);
			deleteBtn.setEnabled(true);
		}

		getWindow().addWindow(eventWindowModal);
	}

	private void customizeFormButtons() {
		submitBtn = new NativeButton("Submit");
		submitBtn.setStyleName("defaultBtn");
		
		deleteBtn = new NativeButton("Delete");
		deleteBtn.setStyleName("defaultBtn");
		
		closeBtn = new NativeButton("Close");
		closeBtn.setStyleName("defaultBtn");
		
		submitBtn.addListener(new Button.ClickListener() {

			private static final long serialVersionUID = 1L;

			@SuppressWarnings("unchecked")
			@Override
			public void buttonClick(ClickEvent event) {
				form.commit();

				switch (mode) {
				case ADD:
					event0.setStyleName("default");
					event0.setIdUser(securityManager.getCurrentUser());
					Long eventId = eventService.insertEvent(event0);

					MyCalendarEvent newEvent = new MyCalendarEvent();
					newEvent.setAllDay(event0.isAll_day());
					newEvent.setCaption(event0.getCaption());
					newEvent.setDescription(event0.getDescription());
					newEvent.setEnd(event0.getEnd());
					newEvent.setIdent(eventId);
					newEvent.setStart(event0.getStart());
					newEvent.setStyleName(event0.getStyleName());
					newEvent.setUser(event0.getIdUser());
					dataSource.addEvent(newEvent);
					getWindow().showNotification("New event succesfully added");
					break;
				case EDIT:
					dataSource.removeEvent(defaultCalEvent);
					selectedEventForEdit.setAll_day(event0.isAll_day());
					selectedEventForEdit.setCaption(event0.getCaption());
					selectedEventForEdit.setDescription(event0.getDescription());
					selectedEventForEdit.setEnd(event0.getEnd());
					selectedEventForEdit.setStart(event0.getStart());
					eventService.updateEvent(selectedEventForEdit);

					MyCalendarEvent editedEvent = new MyCalendarEvent();
					editedEvent.setAllDay(selectedEventForEdit.isAll_day());
					editedEvent.setCaption(selectedEventForEdit.getCaption());
					editedEvent.setDescription(selectedEventForEdit
							.getDescription());
					editedEvent.setEnd(selectedEventForEdit.getEnd());
					editedEvent.setIdent(selectedEventForEdit.getIdEvent());
					editedEvent.setStart(selectedEventForEdit.getStart());
					editedEvent.setStyleName(selectedEventForEdit
							.getStyleName());

					dataSource.addEvent(editedEvent);
					getWindow().showNotification("Event succesfully edited");
					break;
				}

				calendarComponent.requestRepaint();

				getWindow().removeWindow(eventWindowModal);
			}
		});

		deleteBtn.addListener(new Button.ClickListener() {

			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				dataSource.removeEvent(defaultCalEvent);
				eventService.deleteEvent(selectedEventForEdit.getIdEvent());
				
				getWindow().showNotification("Event succesfully deleted");
				calendarComponent.requestRepaint();
				getWindow().removeWindow(eventWindowModal);
			}
		});

		closeBtn.addListener(new Button.ClickListener() {

			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				getWindow().removeWindow(eventWindowModal);
			}
		});

	}

	private void nextMonth() {
        rollMonth(1);
    }

    private void previousMonth() {
        rollMonth(-1);
    }

    private void nextDayWeek() {
        rollDayWeek(1);
    }

    private void previousDayWeek() {
        rollDayWeek(-1);
    }

    private void rollMonth(int direction) {
    	// Reset calendar's start time to the target month's first day.
    	cal.add(GregorianCalendar.MONTH, direction);
    	cal.set(GregorianCalendar.DATE,
				cal.getMinimum(GregorianCalendar.DATE));
		cal.set(GregorianCalendar.HOUR_OF_DAY, 0);
		cal.set(GregorianCalendar.MINUTE, 0);
		cal.set(GregorianCalendar.SECOND, 0);
		cal.set(GregorianCalendar.MILLISECOND, 0);
		calendarComponent.setStartDate(cal.getTime());
		cal.add(GregorianCalendar.MONTH, 1);
		cal.add(GregorianCalendar.DATE, -1);
		calendarComponent.setEndDate(cal.getTime());
    }

    private void rollDayWeek(int direction) {
    	if(direction == 1) {
    		ForwardHandler forward = (ForwardHandler) calendarComponent.getHandler(ForwardEvent.EVENT_ID);
    		forward.forward(new ForwardEvent(calendarComponent));
    	} else {
    		BackwardHandler backward = (BackwardHandler) calendarComponent.getHandler(BackwardEvent.EVENT_ID);
    		backward.backward(new BackwardEvent(calendarComponent));
    	}
    }
    
    private void updateCalendarCaption() {
    	switch(currentView) {
    		case MONTH:
    			String month = cal.getDisplayName(GregorianCalendar.MONTH, GregorianCalendar.LONG, calendarComponent.getLocale());
    			calendarComponent.setCaption(month + " " + cal.get(GregorianCalendar.YEAR));
    			break;
    		default:
    			calendarComponent.setCaption("");
    			break;
    	}
    	calendarComponent.requestRepaint();
    }
    
	public class FormWithComplexLayout extends Form {

		private static final long serialVersionUID = 1L;
		private GridLayout ourLayout;

		public FormWithComplexLayout(
				BeanItem<com.cooldatasoft.domain.model.Event> eventItem) {
			ourLayout = new GridLayout(2, 5);
			ourLayout.setMargin(true, false, false, true);
			ourLayout.setSpacing(true);
			setLayout(ourLayout);

			setWriteThrough(false);
			setInvalidCommitted(false);

			setFormFieldFactory(new ProjectFieldFactory());
			setItemDataSource(eventItem);

			setVisibleItemProperties(Arrays.asList(new String[] { "start",
					"end", "caption", "description", "all_day" }));
		}

		@Override
		protected void attachField(Object propertyId, Field field) {
			if (propertyId.equals("start")) {
				ourLayout.addComponent(field, 0, 0);
			} else if (propertyId.equals("end")) {
				ourLayout.addComponent(field, 0, 1);
			} else if (propertyId.equals("caption")) {
				ourLayout.addComponent(field, 0, 2);
			} else if (propertyId.equals("description")) {
				ourLayout.addComponent(field, 0, 3, 1, 3);
			} else if (propertyId.equals("all_day")) {
				ourLayout.addComponent(field, 0, 4);
			}
		}

		private class ProjectFieldFactory extends DefaultFieldFactory {

			private static final long serialVersionUID = 1L;
			private static final String COMMON_FIELD_WIDTH = "150px";
			private static final String DOUBLE_FIELD_WIDTH = "320px";

			@Override
			public Field createField(Item item, Object propertyId,
					Component uiContext) {
				Field f;

				if ("description".equals(propertyId)) {
					f = createTextAreaField(propertyId);
				} else if ("start".equals(propertyId)) {
					f = createDateField(propertyId);
				} else if ("end".equals(propertyId)) {
					f = createDateField(propertyId);
				} else if ("all_day".equals(propertyId)) {
					f = createCheckBox(propertyId);
				} else {
					f = super.createField(item, propertyId, uiContext);
				}

				if ("caption".equals(propertyId)) {
					TextField tf = (TextField) f;
					tf.setNullRepresentation("");
					tf.setRequired(true);
					tf.setImmediate(true);
					tf.setRequiredError("Please enter an event caption");
					tf.setWidth(COMMON_FIELD_WIDTH);
					tf.addValidator(new StringLengthValidator(
							"Name must be 3-25 characters", 3, 25, false));
				} else if ("description".equals(propertyId)) {
					TextArea ta = (TextArea) f;
					ta.setNullRepresentation("");
					ta.setImmediate(true);
					ta.setRequired(true);
					ta.setRequiredError("Please enter an event description");
					ta.setWidth(DOUBLE_FIELD_WIDTH);
				} else if ("start".equals(propertyId)) {
					PopupDateField df = (PopupDateField) f;
					df.setCaption("Event start date");
					df.setRequired(true);
					df.setWidth(COMMON_FIELD_WIDTH);
					df.setResolution(PopupDateField.RESOLUTION_MIN);
				} else if ("end".equals(propertyId)) {
					PopupDateField df = (PopupDateField) f;
					df.setCaption("Event end date");
					df.setRequired(true);
					df.setWidth(COMMON_FIELD_WIDTH);
					df.setResolution(PopupDateField.RESOLUTION_MIN);
				} else if ("all_day".equals(propertyId)) {
					CheckBox cb = (CheckBox) f;
					cb.setCaption("All day");
					cb.setWidth(COMMON_FIELD_WIDTH);
				}
				return f;
			}

			private TextArea createTextAreaField(Object propertyId) {
				TextArea ta = new TextArea();
				ta.setCaption(DefaultFieldFactory
						.createCaptionByPropertyId(propertyId));
				return ta;
			}

			private PopupDateField createDateField(Object propertyId) {
				PopupDateField df = new PopupDateField();
				df.setResolution(PopupDateField.RESOLUTION_MIN);
				df.setLocale(new Locale("sk"));
				df.setImmediate(true);
				return df;
			}

			private CheckBox createCheckBox(Object propertyId) {
				CheckBox cb = new CheckBox();
				cb.setImmediate(true);
				return cb;
			}
		}
	}

	@AutoGenerated
	private VerticalLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new VerticalLayout();
//		mainLayout.setStyleName("calLayout");
		mainLayout.setImmediate(false);
		mainLayout.setWidth("100%");
		mainLayout.setHeight("100%");
		mainLayout.setMargin(true);
		mainLayout.setSpacing(true);
		
		// top-level component properties
		setWidth("100.0%");
		setHeight("100.0%");
		
		// buttonsLayout
		buttonsLayout = new HorizontalLayout();
		buttonsLayout.setImmediate(false);
		buttonsLayout.setWidth("-1px");
		buttonsLayout.setHeight("40px");
		buttonsLayout.setMargin(false);
		mainLayout.addComponent(buttonsLayout);
		mainLayout.setComponentAlignment(buttonsLayout, new Alignment(20));
		
		// calendarPanel
		calendarPanel = buildCalendarPanel();
		mainLayout.addComponent(calendarPanel);
		mainLayout.setExpandRatio(calendarPanel, 1.0f);
		
		return mainLayout;
	}

	@AutoGenerated
	private Panel buildCalendarPanel() {
		// common part: create layout
		calendarPanel = new Panel();
		calendarPanel.setImmediate(false);
		calendarPanel.setWidth("100.0%");
		calendarPanel.setHeight("100.0%");
		calendarPanel.setScrollable(true);
		calendarPanel.setSizeFull();
		
		// calendarLayout
		calendarLayout = buildCalendarLayout();
		calendarPanel.setContent(calendarLayout);
		
		return calendarPanel;
	}

	@AutoGenerated
	private VerticalLayout buildCalendarLayout() {
		// common part: create layout
		calendarLayout = new VerticalLayout();
		calendarLayout.setImmediate(false);
		calendarLayout.setWidth("100.0%");
		calendarLayout.setHeight("-1px");
		calendarLayout.setMargin(true);
		calendarLayout.setSpacing(true);
		
		// calendarComponent
		calendarComponent = new Calendar();
		calendarComponent.setStyleName("calendar");
		calendarComponent.setImmediate(true);
		calendarComponent.setWidth("100.0%");
		calendarComponent.setHeight("800px");
		calendarLayout.addComponent(calendarComponent);
		
		return calendarLayout;
	}
}
